#include "button.h"
#include "systime.h"


#define BTN_TIME_FILTER         50      //按键滤波时间；单位为毫秒
#define BUTTON_PIN_READ()       GPIO_PA03_READ()

//状态机                       
typedef enum {
    BTN_STA_IDLE = 0,               //空闲
    //按键状态采集
    BTN_STA_SKIP,                   //跳变检测
    BTN_STA_FILTER,                 //过滤
    
    BTN_STA_NO_USE
}BTN_STA_E;

//控制块
static struct
{
    timestamp_t          rtb;                    //计时
    uint8_t         status_bits;             //状态位：0为抬起；1为按下
    uint8_t         available_flag;          //按键状态是否可用
    BTN_STA_E       state;                  //状态机
}gBtnCtrl;



static uint8_t    btn_read_hal(void);


static void button_pin_init(void)
{
    stc_gpio_init_t stcGpioInit = {0};
    
    ///< 外设时钟使能
    SYSCTRL_PeriphClkEnable(SYSCTRL_PERICLK_PA);
    
    ///< LED端口初始化
    stcGpioInit.u32Mode = GPIO_MODE_INPUT;
    stcGpioInit.u32Pin  = GPIO_PIN_03;
    stcGpioInit.u32Pull = GPIO_PULL_NONE;
    GPIOA_Init(&stcGpioInit);

}

void button_init(void)
{
    button_pin_init();
    
    gBtnCtrl.status_bits = 0xFF;
    gBtnCtrl.available_flag = FALSE;
    gBtnCtrl.state = BTN_STA_IDLE;
}


void button_task(void)
{
    static uint8_t hal_bits = 0; //引脚位：0为抬起；1为按下
    
    switch(gBtnCtrl.state) {
        case BTN_STA_IDLE:
            gBtnCtrl.state = BTN_STA_SKIP;
            break;
        case BTN_STA_SKIP:
            if(btn_read_hal() != gBtnCtrl.status_bits) {
                hal_bits = btn_read_hal();
                relative_time_add_ms(&gBtnCtrl.rtb, BTN_TIME_FILTER);
                gBtnCtrl.state = BTN_STA_FILTER;
            }
            break;
        case BTN_STA_FILTER:
            if(btn_read_hal() != hal_bits) {
                gBtnCtrl.state = BTN_STA_SKIP;
            } else if(is_relative_time_timeout(&gBtnCtrl.rtb)) {
                gBtnCtrl.status_bits = hal_bits;
                if(!gBtnCtrl.available_flag) {
                    gBtnCtrl.available_flag = TRUE;
                }
                gBtnCtrl.state = BTN_STA_SKIP;
            }
            break;
       default :
            gBtnCtrl.state = BTN_STA_IDLE;
            break;
    
    }
        

}

/*******************************************************************************
** 函数名称 ：  is_btn_available
** 函数功能 ：  按键值是否可用
** 入口参数 ：  
** 出口参数 ：  0为不可用；1为可用
*******************************************************************************/
uint8_t   is_btn_available(void)
{
    return gBtnCtrl.available_flag;
}


/*******************************************************************************
** 函数名称 ：  btn_get_status
** 函数功能 ：  取按键状态
** 入口参数 ：  
** 出口参数 ：  按键状态  0为抬起；1为按下
*******************************************************************************/
uint8_t   btn_get_status(void)
{
    return gBtnCtrl.status_bits;
}



//0为抬起；1为按下
static uint8    btn_read_hal(void)
{
    if(!BUTTON_PIN_READ()) {
        return 1;
    }
    return 0;
}

